/****************************************************************************

	COPYRIGHT(C) MAXSI SOFTWARE, JONAS 'SORTIE' TERMANSEN 2008, 2009, 2010

    This file is part of Maxsi Distribution.

    Maxsi Distribution is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Maxsi Distribution is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    GNU Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with Maxsi Distribution. If not, see <http://www.gnu.org/licenses/>.

	*/ #include "MaxsiDistributionContributors.h" /*

	If you modify this file, please enter your name below and provide contact
	information in MaxsiDistributionContributors.h. For more information please see
	MaxsiDistributionContributors.h.
	
	Contributors to this file:

	- Jonas 'Sortie' Termansen
	- [your name here]

	MaxsiDistribution.dll
	Distributing since 2008

	MaxsiAchievements001.h
	An interface to Achievements.

****************************************************************************/

#include "MaxsiEngine.h"
#include "MaxsiDistributionLink.h"
#include "Data.h"
#include "Thread.h"
#include "Interface.h"
#include "Interfaces.h"

//=============================================================================
//	Make sure we can easily copy paste code from this file to newer interfaces
//	without having to change too much code.
//=============================================================================
// Maxsi Achievement
#ifdef MaxsiAchievement
#undef MaxsiAchievement
#endif
#define MaxsiAchievement MaxsiAchievement001

// Maxsi Achievements Interface
#ifdef MaxsiAchievementsInterface
#undef MaxsiAchievementsInterface
#endif
#define MaxsiAchievementsInterface MaxsiAchievementsInterface001

// Maxsi Distribution Module
#ifdef MaxsiDistributionModule
#undef MaxsiDistributionModule
#endif
#define MaxsiDistributionModule MaxsiDistributionModule001

// Maxsi Distribution Interface
#ifdef MaxsiDistributionInterface
#undef MaxsiDistributionInterface
#endif
#define MaxsiDistributionInterface MaxsiDistributionInterface001

//=============================================================================
//	Define all the GetInterface functions we need!
//=============================================================================

MD_DECLARE_INTERFACE(MaxsiAchievementsInterface, "MaxsiAchievementsInterface001");

MaxsiAchievement::MaxsiAchievement()
{
	AchievementName		=	NULL;
	AchievementDesc		=	NULL;
	Progress			=	0;
	ProgressMax			=	1;
	SessionAchievement	=	false;
	ResourceId			=	0;
}

MaxsiAchievement::~MaxsiAchievement()
{
	if ( AchievementName ) { delete[] AchievementName; }
	if ( AchievementDesc ) { delete[] AchievementDesc; }
}

//=============================================================================
//	char* GetAchievementName();
//
//	Returns a string with the name of this achievement.
//=============================================================================

MESTR* MaxsiAchievement::GetAchievementName()
{
	return AchievementName;
}

//=============================================================================
//	char* GetAchievementDescription();
//
//	Returns a string with the description of this achievement.
//=============================================================================

MESTR* MaxsiAchievement::GetAchievementDescription()
{
	return AchievementDesc;
}

//=============================================================================
//	unsigned int SetAchievementProgress(unsigned int NewProgress);
//
//	Sets the progress of this achievement.
//=============================================================================

unsigned int MaxsiAchievement::SetAchievementProgress(unsigned int NewProgress)
{
	Progress	=	NewProgress;

	return Progress;
}

//=============================================================================
//	unsigned int GetAchievementProgress();
//
//	Returns the progress for this achievement.
//=============================================================================

unsigned int MaxsiAchievement::GetAchievementProgress()
{
	return Progress;
}

//=============================================================================
//	unsigned int GetAchievementProgressMax();
//
//	Returns the max progress for this achievement.
//=============================================================================

unsigned int MaxsiAchievement::GetAchievementProgressMax()
{
	return ProgressMax;
}

//=============================================================================
//	bool IsSessionAchievement();
//
//	Returns whether this achievement is a session achievement. 
//=============================================================================

bool MaxsiAchievement::IsSessionAchievement()
{
	return SessionAchievement;
}

//=============================================================================
//	int LogoResourceId();
//
//	Returns an Id for the logo for this Achievement that can later be retrieved
//	from the MaxsiAchievementsInterface class.
//=============================================================================

int MaxsiAchievement::LogoResourceId()
{
	return ResourceId;
}

MaxsiAchievementsInterface::MaxsiAchievementsInterface()
{
	MDInterface			=	NULL;

	NumAchievements		=	4;

	Achievements		=	new MaxsiAchievement*[NumAchievements];

	for ( size_t I = 0; I < NumAchievements; I++ )
	{
		Achievements[I]	=	new MaxsiAchievement;
	}

	Achievements[0]->AchievementName	=	BuildString(1,"Gabe in the Sky");
	Achievements[0]->AchievementDesc	=	BuildString(1,"Cellophane flowers of yellow and green, towering over your head. Look for the girl with the sun in her eyes, and she's gone.");

	Achievements[1]->AchievementName	=	BuildString(1,"All you need is AR3");
	Achievements[1]->AchievementDesc	=	BuildString(1,"AR3, AR3, AR3, AR3, AR3, AR3, AR3, AR3, AR3, AR3. There's nothing you can suck into a black hole that can't be sucked into a black hole. It's easy.");

	Achievements[2]->AchievementName	=	BuildString(1,"Hey Guy with an Axe!");
	Achievements[2]->AchievementDesc	=	BuildString(1,"Na na na na na na na, na na na na, na na na na, hey Guy with an Axe!");

	Achievements[3]->AchievementName	=	BuildString(1,"I am the Watch!");
	Achievements[3]->AchievementDesc	=	BuildString(1,"I am the Crowbar, they are the Crowbar, I am the Watch. Goo goo ga joob, Goo goo ga joob.");

}

MaxsiAchievementsInterface::~MaxsiAchievementsInterface()
{

}

//=============================================================================
//	bool	GetAchievements(MaxsiAchievement*** ListOut, size_t* NumOut);
//
//	If returns true, the MaxsiAchievement** member pointed to by ListOut is now
//	filled with a pointer pointing to an array of MaxsiAchievement* members
//	each pointing to an achievement. The size_t pointed to by Numout is filled
//	with an integer descibing how many entires are in the array pointed to by
//	the member pointed to by ListOut. When done, call DeleteAchievementList()
//	with the member pointed to by ListOut and the member pointed to by NumOut.
//=============================================================================

bool	MaxsiAchievementsInterface::GetAchievements(MaxsiAchievement*** ListOut, size_t* NumOut)
{
	*ListOut	=	Achievements;
	*NumOut		=	NumAchievements;

	return false;
}

//=============================================================================
//	bool	DeleteAchievementList(MaxsiAchievement** ListOut, size_t NumOut);
//
//	Deletes this achievement array with NumOut members.
//=============================================================================

bool	MaxsiAchievementsInterface::DeleteAchievementList(MaxsiAchievement** ListOut, size_t NumOut)
{
	return false;
}

//=============================================================================
//	MaxsiAchievement*	GetAchievement(MESTR* Achievement);
//
//	Returns the achievement Achievement if such one is found, otherwise NULL.
//=============================================================================

MaxsiAchievement*	MaxsiAchievementsInterface::GetAchievement(MESTR* Achievement)
{
	for ( size_t I = 0; I < NumAchievements; I++ )
	{
		if ( MESTRICMP(Achievements[I]->GetAchievementName(), Achievement) == 0 )
		{
			return Achievements[I];
		}
	}

	return NULL;
}

//=============================================================================
//	bool	UnlockAchievement(MESTR* Achievement);
//
//	Unlocks the achievement called Achievement for the current user and
//	contacts the master server if it was previously locked.
//=============================================================================

bool	MaxsiAchievementsInterface::UnlockAchievement(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	if ( Subject->GetAchievementProgress() == Subject->GetAchievementProgressMax() ) { return false; }

	Subject->SetAchievementProgress(Subject->GetAchievementProgressMax());

	char* String = BuildString(3, "Achievement \"", Achievement, "\" Unlocked!\n");
	MDInterface->SDKMsg(String);
	delete[] String;

	return false;
}

//=============================================================================
//	bool	LockAchievement(MESTR* Achievement);
//
//	Unlocks the achievement called Achievement for the current user and
//	contacts the master server if it was previously unlocked.
//=============================================================================

bool	MaxsiAchievementsInterface::LockAchievement(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	if ( Subject->GetAchievementProgress() == 0 ) { return false; }

	Subject->SetAchievementProgress(0);

	char* String = BuildString(3, "Achievement \"", Achievement, "\" Locked!\n");
	MDInterface->SDKMsg(String);
	delete[] String;

	return false;
}

//=============================================================================
//	bool	SetAchievementProgress(MESTR* Achievement);
//
//	Sets the progress for the achievement called Achievement and contacts
//	the master server if it has changed.
//=============================================================================

bool	MaxsiAchievementsInterface::SetAchievementProgress(MESTR* Achievement, unsigned int Progress)
{	
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	Subject->SetAchievementProgress(Progress);

	return true;
}

//=============================================================================
//	unsigned int	GetAchievementProgress(MESTR* Achievement);
//
//	Returns the progress for this achievement.
//=============================================================================

unsigned int	MaxsiAchievementsInterface::GetAchievementProgress(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return 0; }

	return Subject->GetAchievementProgress();
}

//=============================================================================
//	unsigned int	GetAchievementProgressMax(MESTR* Achievement);
//
//	Returns the max progress for this achievement.
//=============================================================================

unsigned int	MaxsiAchievementsInterface::GetAchievementProgressMax(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return 0; }

	return Subject->GetAchievementProgressMax();
}

//=============================================================================
//	bool	IncrementAchievementProgress(MESTR* Achievement, [unsigned int Progress = 1]);
//
//	Increments the progress for the achievement Achievement with the optional
//	amount Progress. Unlocks the Achievement if adding progress hits the
//	achievement progress max. The Master Server is contacted if Progress is
//	not 0 and Achievement is not a session achievement. The Master Server is
//	not contacted, if Achievement is a session achievement, unless Progress
//	hits the max.
//=============================================================================

bool	MaxsiAchievementsInterface::IncrementAchievementProgress(MESTR* Achievement, unsigned int Progress )
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	Subject->SetAchievementProgress(Subject->GetAchievementProgress()+1);

	return true;
}

//=============================================================================
//	bool	DecrementAchievementProgress(MESTR* Achievement, [unsigned int Progress = 1]);
//
//	Decrements the progress for the achievement Achievement with the optional
//	amount Progress. Unlocks the Achievement if adding progress hits the
//	achievement progress max. Master Server is contacted if Progress is not 0.
//=============================================================================

bool	MaxsiAchievementsInterface::DecrementAchievementProgress(MESTR* Achievement, unsigned int Progress )
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	Subject->SetAchievementProgress(Subject->GetAchievementProgress()-1);

	return true;
}

//=============================================================================
//	bool IsSessionAchievement(MESTR* Achievement);
//
//	Returns whether this achievement is a session achievement. 
//=============================================================================

bool	MaxsiAchievementsInterface::IsSessionAchievement(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return false; }

	return Subject->IsSessionAchievement();
}

//=============================================================================
//	bool	SessionFailedUnlock(MESTR* Achievement);
//
//	This per-session attempt to unlock Achievement failed.
//=============================================================================

bool	MaxsiAchievementsInterface::SessionUnlockFailed(MESTR* Achievement)
{
	return false;
}

//=============================================================================
//	bool	SessionUnlockAttempt(MESTR* Achievement);
//
//	This per-session attempt to unlock Achievement has not failed yet.
//=============================================================================

bool	MaxsiAchievementsInterface::SessionUnlockAttempt(MESTR* Achievement)
{
	return false;
}

//=============================================================================
//	bool	SessionFailedUnlock(MESTR* Achievement);
//
//	All session achievements - that has not failed yet - are hereby completed.
//	The Master Server is instantly contacted and notified by the success, if
//	any achievements were unlocked. The Master Server is not contacted if no
//	session achievements were unlocked.
//=============================================================================

bool	MaxsiAchievementsInterface::SessionUnlockSucceded(MESTR* Achievement)
{
	return false;
}

//=============================================================================
//	int LogoResourceId(MESTR* Achievement);
//
//	Returns an Id for the logo for this Achievement that can later be retrieved
//	from the MaxsiAchievementsInterface class.
//=============================================================================

int		MaxsiAchievementsInterface::LogoResourceId(MESTR* Achievement)
{
	MaxsiAchievement*	Subject		=	GetAchievement(Achievement);

	if ( Subject == NULL ) { return 0; }

	return Subject->LogoResourceId();
}

//=============================================================================
//	bool GetLogoResource(char** BufferOut, size_t* BufferLengthOut, int ResourcId, int AchievementStatus );
//
//	Returns true if BufferOut gives a data buffer containing BufferLengthOut
//	bytes giving the resource pointed by ResourceId and AchievementStatus
//	which takes the two values: MD_ACHIEVEMENT_UNLOCKED and
//	MD_ACHIEVEMENT_LOCKED.
//=============================================================================

bool	MaxsiAchievementsInterface::GetLogoResource(char** BufferOut, size_t* BufferLengthOut, int ResourcId, int AchievementStatus )
{
	return false;
}

//=============================================================================
//	char*	GetModuleName()
//
//	Returns a static string with the name of this particular MD Module.
//=============================================================================

MESTR*	MaxsiAchievementsInterface::GetModuleName()
{
	return _MESTR("MaxsiAchievements");
}

//=============================================================================
//	bool	SetMaxsiDistributionInterface(MaxsiDistributionInterface* Interface)
//
//	Returns a static string with the name of this particular MD Module.
//=============================================================================

bool	MaxsiAchievementsInterface::SetMaxsiDistributionInterface(MaxsiDistributionInterface* Interface)
{
	MDInterface	=	Interface;
	return true;
}

//=============================================================================
//	bool	CreateSession();
//
//	Terminates all data belonging to previous sessions and creates a new default
//	session. A ses
//=============================================================================

bool	MaxsiAchievementsInterface::CreateSession()
{
	return false;
}

//=============================================================================
//	bool	SaveSession(char** OutBuffer, size_t* OutBufferLength);
//
//	Exports a buffer with all the session-data this module needs to store
//	permanently for this session specificly. The application should take care
//	of storing this and passing it onto RestoreSession() when the session is
//	restored. OutBuffer points to a	char* which will be changed to point to a
//	buffer containing OutBufferLength bytes that should be saved. Call
//	SavedSession() when done with the buffer.
//=============================================================================

bool	MaxsiAchievementsInterface::SaveSession(char** OutBuffer, size_t* OutBufferLength)
{
	return false;
}

//=============================================================================
//	bool	SavedSession(char* OutBuffer, size_t OutBufferLength);
//
//	Deletes the buffer allocated for use by the application when SaveSession()
//	is called. You must call SavedSession() when done with the buffer.
//=============================================================================

bool	MaxsiAchievementsInterface::SavedSession(char* OutBuffer, size_t OutBufferLength)
{
	return false;
}

//=============================================================================
//	bool	RestoreSession(char* OutBuffer, size_t OutBufferLength);
//
//	Restores a previous session.
//=============================================================================

bool	MaxsiAchievementsInterface::RestoreSession(char* Buffer, size_t BufferLength)
{
	return false;
}